#include "m4aformat.h"

// 1111 1111 1111  0 00 1 01 0011 00 0100 0000 0010 1010 1010 0001 1010 10
/*
ADTSHeader : 7 or 9 bit adts_fixed_header +   adts_variable_header 
adts_fixed_header()
{
	syncword;					12     1111 1111 1111
	ID;							1       0
	layer;						2      00
	protection_absent;			1       1
	profile_ObjectType;			2 
	sampling_frequency_index;	4 
	private_bit;				1 
	channel_configuration;		3 
	original_copy;				1 
	home;						1 
}
adts_variable_header()
{
	copyright_identification_bit;		1 
	copyright_identification_start;		1 
	aac_frame_length;					13 
	adts_buffer_fullness;				11 
	number_of_raw_data_blocks_in_frame; 2 
}
CRC -----> 2byte  optional
*/
/*
 @ 不带CRC的AAC头部解析保存 
*/
int mpeg4_aac_adts_save(const struct mpeg4_aac_t* aac, size_t payload, uint8_t* data, size_t bytes)
{
    const uint8_t ID = 0; // 0-MPEG4/1-MPEG2
	size_t len = payload + 7;

	if (bytes < 7 || len >= (1 << 12))
        return -1;
	if (0 == aac->channel_configuration && aac->npce > 0)
		len += mpeg4_aac_adts_pce_save(data, bytes, aac);

	assert(aac->profile > 0 && aac->profile < 31);
	assert(aac->channel_configuration >= 0 && aac->channel_configuration <= 7);
	assert(aac->sampling_frequency_index >= 0 && aac->sampling_frequency_index <= 0xc);
	data[0] = 0xFF;   // 分界符
	data[1] = 0xF0 | (ID << 3) | (0x00 << 2) | 0x01; //分界符低四位 + 代表 MPEG4 的 AAC + 固定填充 00 + 不使用CRC
	data[2] = ((aac->profile - 1) << 6) | ((aac->sampling_frequency_index & 0x0F) << 2) | ((aac->channel_configuration >> 2) & 0x01); // 哪个级别和规范的AAC + Private Bit + 采样率下标 + 通道配置即声道数(最高位)
	data[3] = ((aac->channel_configuration & 0x03) << 6) | ((len >> 11) & 0x03);   // 通道配置即声道数(低两位) +  4bit都是0的没用信息 + 2bit Aac Frame Length
	data[4] = (uint8_t)(len >> 3);    // 8bit Aac Frame Length
	data[5] = ((len & 0x07) << 5) | 0x1F;   // 3 bit Aac Frame Length + 11bit ADTS Buffer Fullness(1111 1111 111 表示码率可变的码流；0000 0000 000表示码率不可变的码流)
	data[6] = 0xFC;// 1111 11 01    2bit Number of AAC Frames this is 1；
	return (int)(len - payload);
}
// get dats header
int mpeg4_aac_adts_load(const uint8_t* data, size_t bytes, struct mpeg4_aac_t* aac)
{
	if (bytes < 7) return -1;

	memset(aac, 0, sizeof(struct mpeg4_aac_t));
	assert(0xFF == data[0] && 0xF0 == (data[1] & 0xF0)); /* fff */
	aac->profile = ((data[2] >> 6) & 0x03) + 1; //
	aac->sampling_frequency_index = (data[2] >> 2) & 0x0F; // 
	aac->channel_configuration = ((data[2] & 0x01) << 2) | ((data[3] >> 6) & 0x03); // 
	assert(aac->profile > 0 && aac->profile < 31);
	assert(aac->channel_configuration >= 0 && aac->channel_configuration <= 7);
	assert(aac->sampling_frequency_index >= 0 && aac->sampling_frequency_index <= 0xc);
    // AAC 解码配置
	aac->channels = mpeg4_aac_channel_count(aac->channel_configuration);
	aac->sampling_frequency = mpeg4_aac_audio_frequency_to(aac->sampling_frequency_index);
	aac->extension_frequency = aac->sampling_frequency;

	if (0 == aac->channel_configuration)
		return mpeg4_aac_adts_pce_load(data, bytes, aac);
	return 7;
}
// get audio 详细配置
int mpeg4_aac_audio_specific_config_load(const uint8_t* data, size_t bytes, struct mpeg4_aac_t* aac)
{
	if (bytes < 2) return -1;

	memset(aac, 0, sizeof(struct mpeg4_aac_t));
	aac->profile = (data[0] >> 3) & 0x1F;
	aac->sampling_frequency_index = ((data[0] & 0x7) << 1) | ((data[1] >> 7) & 0x01);
	aac->channel_configuration = (data[1] >> 3) & 0x0F;
	assert(aac->profile > 0 && aac->profile < 31);
	assert(aac->channel_configuration >= 0 && aac->channel_configuration <= 7);
	assert(aac->sampling_frequency_index >= 0 && aac->sampling_frequency_index <= 0xc);
	aac->channels = mpeg4_aac_channel_count(aac->channel_configuration);   // 计算通道数量
	aac->sampling_frequency = mpeg4_aac_audio_frequency_to(aac->sampling_frequency_index);  // 采样率下标计算采样率
	aac->extension_frequency = aac->sampling_frequency;

	if (bytes > 2)
		return mpeg4_aac_audio_specific_config_load2(data, bytes, aac);
	return 2;
}
int mpeg4_aac_audio_specific_config_save(const struct mpeg4_aac_t* aac, uint8_t* data, size_t bytes)
{
	uint8_t channel_configuration;
	if (bytes < 2+ (size_t)aac->npce) return -1;

	channel_configuration = aac->npce > 0 ? 0 : aac->channel_configuration;
	assert(aac->profile > 0 && aac->profile < 31);
	assert(aac->channel_configuration >= 0 && aac->channel_configuration <= 7);
	assert(aac->sampling_frequency_index >= 0 && aac->sampling_frequency_index <= 0xc);
	data[0] = (aac->profile << 3) | ((aac->sampling_frequency_index >> 1) & 0x07);
	data[1] = ((aac->sampling_frequency_index & 0x01) << 7) | ((channel_configuration & 0xF) << 3) | (0 << 2) | (0 << 1) | 0 ;

	if (0 == aac->channel_configuration && aac->npce > 0)
		return mpeg4_aac_audio_specific_config_save2(aac, data, bytes);   // 当声道数量为0 并且存在pce的时候，将pce拷到缓存区
	return 2;
}

int mpeg4_aac_stream_mux_config_load(const uint8_t* data, size_t bytes, struct mpeg4_aac_t* aac)
{
	if (bytes < 6) return -1;

	memset(aac, 0, sizeof(*aac));
	if (6 == bytes && 0x40 == data[0] && 0 == (data[1] & 0xFE))
	{
		// fast path
		assert(0 == (0x80 & data[0])); // audioMuxVersion: 0
		aac->profile = ((data[1] & 0x01) << 4) | (data[2] >> 4); // 0-numProgram(4), 0-numLayer(3), 1-ASC(1)
		aac->sampling_frequency_index = data[2] & 0x0F;
		aac->channel_configuration = data[3] >> 4;
		assert(aac->profile > 0 && aac->profile < 31);
		assert(aac->channel_configuration >= 0 && aac->channel_configuration <= 7);
		assert(aac->sampling_frequency_index >= 0 && aac->sampling_frequency_index <= 0xc);
		aac->channels = mpeg4_aac_channel_count(aac->channel_configuration);
		aac->sampling_frequency = mpeg4_aac_audio_frequency_to(aac->sampling_frequency_index);
		aac->extension_frequency = aac->sampling_frequency;
		return 6;
	}
	return mpeg4_aac_stream_mux_config_load2(data, bytes, aac);
}
int mpeg4_aac_stream_mux_config_save(const struct mpeg4_aac_t* aac, uint8_t* data, size_t bytes)
{
	if (bytes < 6) return -1;

	assert(aac->profile > 0 && aac->profile < 31);
	assert(aac->channel_configuration >= 0 && aac->channel_configuration <= 7);
	assert(aac->sampling_frequency_index >= 0 && aac->sampling_frequency_index <= 0xc);
	data[0] = 0x40; // 0-audioMuxVersion(1), 1-allStreamsSameTimeFraming(1), 0-numSubFrames(6)
	//data[1] = 0x00 | ((aac->profile >> 4) & 0x01); // 0-numProgram(4), 0-numLayer(3)
	//data[2] = ((aac->profile & 0x0F) << 4) | (aac->sampling_frequency_index & 0x0F);
	data[1] = 0x00;
	data[2] = 0x20 | (aac->sampling_frequency_index & 0x0F); // AAC_LC profile
	data[3] = ((aac->channel_configuration & 0x0F) << 4) | 0; // 0-GASpecificConfig(3), 0-frameLengthType(1)
	data[4] = 0x3F; // 0-frameLengthType(2), 111111-latmBufferFullness(6)
	data[5] = 0xC0; // 11-latmBufferFullness(2), 0-otherDataPresent, 0-crcCheckPresent
	return 6;
}

// int mpeg4_aac_profile_level(const struct mpeg4_aac_t* aac)
// {
// 	// Table 1.10 - Levels for the AAC Profile (p49)
// 	// Table 1.14 - audioProfileLevelIndication values (p51)
// 	switch (aac->profile)
// 	{
// 	case MPEG4_AAC_LC:
// 		return mpeg4_aac_level(aac) - 1 + 0x28; // AAC Profile
// 	case MPEG4_AAC_SBR:
// 		return mpeg4_aac_he_level(aac) - 2 + 0x2C; // High Efficiency AAC Profile
// 	case MPEG4_AAC_PS:
// 		return mpeg4_aac_he_level(aac) - 2 + 0x30; // High Efficiency AAC v2 Profile
// 	case MPEG4_AAC_CELP:
// 		return mpeg4_aac_high_quality_level(aac) - 1 + 0x0E; // High Quality Audio Profile
// 	default:
// 		return 1; // Main Audio Profile, Level 1
// 	}
// }
#define ARRAYOF(arr) sizeof(arr)/sizeof(arr[0])
static const int s_frequency[] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350 };
int mpeg4_aac_audio_frequency_to(enum mpeg4_aac_frequency index)
{
	if (index < 0 || index >= ARRAYOF(s_frequency))
		return 0;
	return s_frequency[index];    // 通过频率下标返回采样率
}
int mpeg4_aac_audio_frequency_from(int frequence)
{
	int i = 0;
	while (i < ARRAYOF(s_frequency) && s_frequency[i] != frequence) i++;
	return i >= ARRAYOF(s_frequency) ? -1 : i;   // 采样率下标
}


uint8_t mpeg4_aac_channel_count(uint8_t channel_configuration)
{
	static const uint8_t s_channels[] = { 0, 1, 2, 3, 4, 5, 6, 8 };
	if (channel_configuration < 0 || channel_configuration >= ARRAYOF(s_channels))
		return 0;
	return s_channels[channel_configuration];   // 通道数量
}
/*
 @：获取当前数据第一帧的长度
*/
int mpeg4_aac_adts_frame_length(const uint8_t* data, size_t bytes)
{
	uint16_t len;
	if (bytes < 7) return -1;
	assert(0xFF == data[0] && 0xF0 == (data[1] & 0xF0)); /* syncword */
	len = ((uint16_t)(data[3] & 0x03) << 11) | ((uint16_t)data[4] << 3) | ((uint16_t)(data[5] >> 5) & 0x07);
	return len;
}



// int mpeg4_aac_stream_mux_config_load2(const uint8_t* data, size_t bytes, struct mpeg4_aac_t* aac)
// {
// 	struct mpeg4_bits_t bits;
// 	mpeg4_bits_init(&bits, (void*)data, bytes);
// 	mpeg4_aac_stream_mux_config_load3(&bits, aac);
// 	mpeg4_bits_aligment(&bits, 8);
// 	return mpeg4_bits_error(&bits) ? -1 : (int)(bits.bits / 8);
// }






